<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="utf-8" />
    
  <meta name="description" content="林湃滨的个人博客" />
  
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
  <title>
     滨书
  </title>
  <meta name="generator" content="hexo-theme-yilia-plus">
  
  <link rel="shortcut icon" href="/favicon.ico" />
  
  
<link rel="stylesheet" href="/css/style.css">

  
<script src="/js/pace.min.js"></script>


  

  

<link rel="alternate" href="/atom.xml" title="滨书" type="application/atom+xml">
</head>

</html>

<body>
  <div id="app">
    <main class="content">
      
<section class="cover">
    
  <div class="cover-frame">

    <div class="bg-box">
      <img src="/images/coverWLOP.jpg" alt="image frame" />
    </div>
      <iframe style="display: inline-block;float: right;margin: 10px;" frameborder="no" border="0" marginwidth="0" marginheight="0" width=330 height=450 src="//music.163.com/outchain/player?type=0&id=4901576078&auto=1&height=430"></iframe>

    
    <div class="cover-inner text-center text-white">
      <h1><a href="/">滨书</a></h1>
      <div id="subtitle-box">
        
        <span id="subtitle"></span>
        
      </div>
      <div>
        
      </div>
    </div>
  </div>
  <div class="cover-learn-more">
    <a href="javascript:void(0)" class="anchor"><i class="ri-arrow-down-line"></i></a>
  </div>
</section>



<script src="https://cdn.jsdelivr.net/npm/typed.js@2.0.11/lib/typed.min.js"></script>


<div id="main">
  <section class="outer">
  <article class="articles">
    
    
    
    
    <article id="post-IdeaTools/IDEA-快捷键大全" class="article article-type-post" itemscope
  itemprop="blogPost" data-scroll-reveal>

  <div class="article-inner">
    
    <header class="article-header">
       
<h2 itemprop="name">
  <a class="article-title" href="/2019/12/07/IdeaTools/IDEA-%E5%BF%AB%E6%8D%B7%E9%94%AE%E5%A4%A7%E5%85%A8/"
    >IDEA 快捷键大全</a
  >
</h2>
  

    </header>
    

    
    <div class="article-meta">
      <a href="/2019/12/07/IdeaTools/IDEA-%E5%BF%AB%E6%8D%B7%E9%94%AE%E5%A4%A7%E5%85%A8/" class="article-date">
  <time datetime="2019-12-07T14:03:15.000Z" itemprop="datePublished">2019-12-07</time>
</a>
      
      
      
      
    </div>
    

    

    <div class="article-entry" itemprop="articleBody">
      


      

      
      <p>[toc]</p>
<h2 id="常用快捷键"><a href="#常用快捷键" class="headerlink" title="常用快捷键"></a>常用快捷键</h2><blockquote>
<p>Ctrl + Shift + A 快捷键可以查找 Intellij 的所有命令，且有带有其快捷键信息，可谓一大神键，也适合我们了解、学习快捷键的工具。</p>
</blockquote>
<h3 id="自动代码快捷键"><a href="#自动代码快捷键" class="headerlink" title="自动代码快捷键"></a>自动代码快捷键</h3><table>
<thead>
<tr>
<th align="center">快捷键（括号内为笔记解释）</th>
<th align="center">含义</th>
</tr>
</thead>
<tbody><tr>
<td align="center">Ctrl + Alt + O</td>
<td align="center">优化导入的类和包</td>
</tr>
<tr>
<td align="center">Alt + Insert</td>
<td align="center">生成代码(如get,set方法,构造函数等)</td>
</tr>
<tr>
<td align="center">fori/sout/psvm + Tab</td>
<td align="center">快捷生成 循环/输出/main函数</td>
</tr>
<tr>
<td align="center">Ctrl+Alt+T</td>
<td align="center">生成try catch</td>
</tr>
<tr>
<td align="center">Ctrl + O （Override）</td>
<td align="center">重写方法</td>
</tr>
<tr>
<td align="center">Ctrl + I （Implement）</td>
<td align="center">实现方法</td>
</tr>
<tr>
<td align="center">Ctr+shift+U</td>
<td align="center">大小写转化</td>
</tr>
<tr>
<td align="center">ALT+回车</td>
<td align="center">导入包，自动改正</td>
</tr>
<tr>
<td align="center">ALT + /</td>
<td align="center">代码提示（对应Eclipse）</td>
</tr>
<tr>
<td align="center">Ctrl + J</td>
<td align="center">自动代码</td>
</tr>
<tr>
<td align="center">Ctrl + Shift + J</td>
<td align="center">整合两行为一行</td>
</tr>
<tr>
<td align="center">Ctrl + space</td>
<td align="center">代码提示</td>
</tr>
<tr>
<td align="center">Ctrl + Shift + space</td>
<td align="center">自动补全代码</td>
</tr>
<tr>
<td align="center">Ctrl + Alt + L</td>
<td align="center">格式化代码</td>
</tr>
<tr>
<td align="center">Ctrl + Alt + I</td>
<td align="center">自动缩进</td>
</tr>
<tr>
<td align="center">Ctrl + E</td>
<td align="center">查看最近更改的代码</td>
</tr>
<tr>
<td align="center">Ctrl + Alt + space</td>
<td align="center">类名或接口名提示</td>
</tr>
<tr>
<td align="center">Ctrl + P</td>
<td align="center">方法参数提示</td>
</tr>
<tr>
<td align="center">Ctrl + Q</td>
<td align="center">可以看到当前方法的声明</td>
</tr>
<tr>
<td align="center">Shift + F6</td>
<td align="center">重构-重命名（包、类、方法、变量、注释等）</td>
</tr>
<tr>
<td align="center">Ctrl + Alt + V</td>
<td align="center">提取变量</td>
</tr>
<tr>
<td align="center"></td>
<td align="center"></td>
</tr>
<tr>
<td align="center"></td>
<td align="center"></td>
</tr>
<tr>
<td align="center"></td>
<td align="center"></td>
</tr>
</tbody></table>
<h3 id="查询快捷键"><a href="#查询快捷键" class="headerlink" title="查询快捷键"></a>查询快捷键</h3><table>
<thead>
<tr>
<th align="center">快捷键</th>
<th align="center">含义</th>
</tr>
</thead>
<tbody><tr>
<td align="center">Ctrl + Shift + Backspace</td>
<td align="center">跳转到上次编辑的地方</td>
</tr>
<tr>
<td align="center">Ctrl + Alt + Left/Right</td>
<td align="center">前后导航编辑过的地方</td>
</tr>
<tr>
<td align="center">Alt + 7</td>
<td align="center">靠左窗口显示当前文件的结构</td>
</tr>
<tr>
<td align="center">Ctrl + F12</td>
<td align="center">浮动显示当前文件的结构</td>
</tr>
<tr>
<td align="center">Alt + F7</td>
<td align="center">找到你的函数/变量/类的所有引用到的地方</td>
</tr>
<tr>
<td align="center">Ctrl + Alt + F7</td>
<td align="center">找到你的函数/变量/类的所有引用到的地方</td>
</tr>
<tr>
<td align="center">Ctrl + Shift + Alt + N</td>
<td align="center">查找类中的方法或者变量</td>
</tr>
<tr>
<td align="center">double Shift</td>
<td align="center">在项目中的所有目录查找文件</td>
</tr>
<tr>
<td align="center">Ctrl + N</td>
<td align="center">查找类</td>
</tr>
<tr>
<td align="center">Ctrl + Shift + N</td>
<td align="center">查找文件</td>
</tr>
<tr>
<td align="center">Ctrl + G</td>
<td align="center">定位行</td>
</tr>
<tr>
<td align="center">Ctrl + F</td>
<td align="center">在当前窗口查找文本</td>
</tr>
<tr>
<td align="center">Ctrl + Shift + F</td>
<td align="center">在指定窗口查找文本</td>
</tr>
<tr>
<td align="center">Ctrl + R</td>
<td align="center">当前窗口口替换文本</td>
</tr>
<tr>
<td align="center">Ctrl + Shift + R</td>
<td align="center">在指定窗口替换文本</td>
</tr>
<tr>
<td align="center">Alt + Shift + C</td>
<td align="center">查找修改的文本</td>
</tr>
<tr>
<td align="center">Ctrl + E</td>
<td align="center">最近打开的文件</td>
</tr>
<tr>
<td align="center">F3</td>
<td align="center">向下查找关键字出现的位置</td>
</tr>
<tr>
<td align="center">Shift + F3</td>
<td align="center">向上查找关键字出现的位置</td>
</tr>
<tr>
<td align="center">F4</td>
<td align="center">查找变量来源</td>
</tr>
<tr>
<td align="center">Ctrl + Shift + O</td>
<td align="center">弹出显示查找内容</td>
</tr>
<tr>
<td align="center">Ctrl + W</td>
<td align="center">选中代码（连续按会有其他效果）</td>
</tr>
<tr>
<td align="center">F2 / Shift + F2</td>
<td align="center">高亮error/warning快速定位</td>
</tr>
<tr>
<td align="center">Ctrl + UP/Down</td>
<td align="center">光标跳转到第一行或最后一行下</td>
</tr>
<tr>
<td align="center">Ctrl + B</td>
<td align="center">快速打开光标处的类或者方法</td>
</tr>
<tr>
<td align="center">Ctrl + Alt + B</td>
<td align="center">查找所有的子类</td>
</tr>
<tr>
<td align="center">Ctrl + Shift + B</td>
<td align="center">查找变量的类</td>
</tr>
<tr>
<td align="center">Ctrl + Alt + Left/Right</td>
<td align="center">返回到上次浏览过的位置</td>
</tr>
<tr>
<td align="center">Ctrl + Shift + Up/Down</td>
<td align="center">上下移动代码</td>
</tr>
<tr>
<td align="center">Ctrl + X</td>
<td align="center">删除行</td>
</tr>
<tr>
<td align="center">Ctrl + D</td>
<td align="center">复制行</td>
</tr>
<tr>
<td align="center">Ctrl + H</td>
<td align="center">显示类结构图</td>
</tr>
<tr>
<td align="center">Ctrl + Q</td>
<td align="center">显示注释文档</td>
</tr>
<tr>
<td align="center">Alt + F1</td>
<td align="center">查找代码所在位置</td>
</tr>
<tr>
<td align="center">Alt + 1</td>
<td align="center">快速打开或隐藏工程面板</td>
</tr>
<tr>
<td align="center">Alt + Left/Right</td>
<td align="center">切换代码视图</td>
</tr>
<tr>
<td align="center">Alt + Up/Down</td>
<td align="center">在方法之间快速移动定位</td>
</tr>
<tr>
<td align="center">Ctrl + Alt + Left/Right</td>
<td align="center">前后导航编辑过的地方</td>
</tr>
<tr>
<td align="center">Alt + 6</td>
<td align="center">查找TODO</td>
</tr>
<tr>
<td align="center"></td>
<td align="center"></td>
</tr>
<tr>
<td align="center"></td>
<td align="center"></td>
</tr>
<tr>
<td align="center"></td>
<td align="center"></td>
</tr>
</tbody></table>
<h3 id="其他快捷键"><a href="#其他快捷键" class="headerlink" title="其他快捷键"></a>其他快捷键</h3><table>
<thead>
<tr>
<th align="center">快捷键</th>
<th align="center">含义</th>
</tr>
</thead>
<tbody><tr>
<td align="center">Shift + Enter</td>
<td align="center">另起一行</td>
</tr>
<tr>
<td align="center">Ctrl + Shift + Z</td>
<td align="center">取消之前的撤销操作</td>
</tr>
<tr>
<td align="center">Ctrl + Alt + F12</td>
<td align="center">资源管理器打开文件夹</td>
</tr>
<tr>
<td align="center">Alt + F1</td>
<td align="center">查找文件所在目录位置</td>
</tr>
<tr>
<td align="center">Shift + Alt + Insert</td>
<td align="center">竖编辑模式</td>
</tr>
<tr>
<td align="center">Ctrl + F4</td>
<td align="center">关闭当前窗口</td>
</tr>
<tr>
<td align="center">Ctrl + Alt + V</td>
<td align="center">自动导入变量定义</td>
</tr>
<tr>
<td align="center">Ctrl + ~</td>
<td align="center">快速切换方案（如界面外观、代码风格、快捷键映射等）</td>
</tr>
</tbody></table>
<h3 id="调试快捷键"><a href="#调试快捷键" class="headerlink" title="调试快捷键"></a>调试快捷键</h3><table>
<thead>
<tr>
<th align="center">快捷键</th>
<th align="center">含义</th>
</tr>
</thead>
<tbody><tr>
<td align="center">Alt + F8</td>
<td align="center">debug时选中，查看值</td>
</tr>
<tr>
<td align="center">Alt + F9</td>
<td align="center">运行至光标处</td>
</tr>
<tr>
<td align="center">F9</td>
<td align="center">恢复程序</td>
</tr>
<tr>
<td align="center">Alt+F10</td>
<td align="center">定位到断点</td>
</tr>
</tbody></table>
<h3 id="重构快捷键"><a href="#重构快捷键" class="headerlink" title="重构快捷键"></a>重构快捷键</h3><table>
<thead>
<tr>
<th align="center">快捷键</th>
<th align="center">含义</th>
</tr>
</thead>
<tbody><tr>
<td align="center">Ctrl + Alt + Shift + T</td>
<td align="center">弹出重构菜单</td>
</tr>
<tr>
<td align="center">Shift+F6</td>
<td align="center">重命名</td>
</tr>
<tr>
<td align="center">Alt + Delete</td>
<td align="center">安全删除</td>
</tr>
<tr>
<td align="center">Ctrl + Alt + N</td>
<td align="center">内联</td>
</tr>
</tbody></table>

      
      <!-- reward -->
      
    </div>
      <!-- copyright -->
      
    <footer class="article-footer">
      
      
  <ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/IDEA/" rel="tag">IDEA</a></li></ul>


    </footer>

  </div>

  

  
  
  

  

</article>
    
    <article id="post-AboutMe" class="article article-type-post" itemscope
  itemprop="blogPost" data-scroll-reveal>

  <div class="article-inner">
    
    <header class="article-header">
       
<h2 itemprop="name">
  <a class="article-title" href="/2019/12/02/AboutMe/"
    >AboutMe</a
  >
</h2>
  

    </header>
    

    
    <div class="article-meta">
      <a href="/2019/12/02/AboutMe/" class="article-date">
  <time datetime="2019-12-02T13:37:04.000Z" itemprop="datePublished">2019-12-02</time>
</a>
      
      
      
      
    </div>
    

    

    <div class="article-entry" itemprop="articleBody">
      


      

      
      <h1 id="林湃滨"><a href="#林湃滨" class="headerlink" title="林湃滨"></a>林湃滨</h1><blockquote>
<p>A Student  living in GuangZhou China.</p>
</blockquote>
<p>来自：广东省揭阳市</p>
<p>就读学校：广州大学</p>
<p>各社区账号：</p>
<p>【QQ邮箱】<a href="mailto:252834399@qq.com">252834399@qq.com</a></p>
<p>【<a href="https://gitee.com/linpaibin" target="_blank" rel="noopener">码云Gitee</a>】</p>
<p>【<a href="https://github.com/LPB-Devin" target="_blank" rel="noopener">GitHub</a>】</p>
<p>【<a href="https://me.csdn.net/weixin_40849588" target="_blank" rel="noopener">CSDN</a>】</p>
<blockquote>
<p>不过以后会比较专心于自己的博客小基地，CSDN社区的账号可能会比以前少花精力了嘻嘻</p>
</blockquote>

      
      <!-- reward -->
      
    </div>
      <!-- copyright -->
      
    <footer class="article-footer">
      
      
  <ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/AboutMe/" rel="tag">AboutMe</a></li></ul>


    </footer>

  </div>

  

  
  
  

  

</article>
    
    <article id="post-Java/Java正则表达式语法" class="article article-type-post" itemscope
  itemprop="blogPost" data-scroll-reveal>

  <div class="article-inner">
    
    <header class="article-header">
       
<h2 itemprop="name">
  <a class="article-title" href="/2019/11/05/Java/Java%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F%E8%AF%AD%E6%B3%95/"
    >Java正则表达式语法</a
  >
</h2>
  

    </header>
    

    
    <div class="article-meta">
      <a href="/2019/11/05/Java/Java%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F%E8%AF%AD%E6%B3%95/" class="article-date">
  <time datetime="2019-11-05T14:38:31.000Z" itemprop="datePublished">2019-11-05</time>
</a>
      
      
      
      
    </div>
    

    

    <div class="article-entry" itemprop="articleBody">
      


      

      
      
      
      <!-- reward -->
      
    </div>
      <!-- copyright -->
      
    <footer class="article-footer">
      
      
  <ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/Java/" rel="tag">Java</a></li></ul>


    </footer>

  </div>

  

  
  
  

  

</article>
    
    <article id="post-Java/Deepin配置Java开发环境" class="article article-type-post" itemscope
  itemprop="blogPost" data-scroll-reveal>

  <div class="article-inner">
    
    <header class="article-header">
       
<h2 itemprop="name">
  <a class="article-title" href="/2019/11/03/Java/Deepin%E9%85%8D%E7%BD%AEJava%E5%BC%80%E5%8F%91%E7%8E%AF%E5%A2%83/"
    >【Deepin】配置Java开发环境</a
  >
</h2>
  

    </header>
    

    
    <div class="article-meta">
      <a href="/2019/11/03/Java/Deepin%E9%85%8D%E7%BD%AEJava%E5%BC%80%E5%8F%91%E7%8E%AF%E5%A2%83/" class="article-date">
  <time datetime="2019-11-02T18:04:54.000Z" itemprop="datePublished">2019-11-03</time>
</a>
      
  <div class="article-category">
    <a class="article-category-link" href="/categories/Deepin%E7%9B%B8%E5%85%B3/">Deepin相关</a>
  </div>

      
      
      
    </div>
    

    

    <div class="article-entry" itemprop="articleBody">
      


      

      
      <h2 id="官网下载JDK"><a href="#官网下载JDK" class="headerlink" title="官网下载JDK"></a>官网下载JDK</h2><h2 id="配置路径"><a href="#配置路径" class="headerlink" title="配置路径"></a>配置路径</h2><p>设置默认JDK版本，以及配置可选JDK版本</p>
<h2 id="测试"><a href="#测试" class="headerlink" title="测试"></a>测试</h2>
      
      <!-- reward -->
      
    </div>
      <!-- copyright -->
      
    <footer class="article-footer">
      
      
  <ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/Java/" rel="tag">Java</a></li></ul>


    </footer>

  </div>

  

  
  
  

  

</article>
    
    <article id="post-XSS攻击" class="article article-type-post" itemscope
  itemprop="blogPost" data-scroll-reveal>

  <div class="article-inner">
    
    <header class="article-header">
       
<h2 itemprop="name">
  <a class="article-title" href="/2019/11/02/XSS%E6%94%BB%E5%87%BB/"
    >【XSS攻击】XSS攻击简介以及预防</a
  >
</h2>
  

    </header>
    

    
    <div class="article-meta">
      <a href="/2019/11/02/XSS%E6%94%BB%E5%87%BB/" class="article-date">
  <time datetime="2019-11-02T00:49:33.000Z" itemprop="datePublished">2019-11-02</time>
</a>
      
  <div class="article-category">
    <a class="article-category-link" href="/categories/XSS/">XSS</a>
  </div>

      
      
      
    </div>
    

    

    <div class="article-entry" itemprop="articleBody">
      


      

      
      <h2 id="1、XSS攻击"><a href="#1、XSS攻击" class="headerlink" title="1、XSS攻击"></a>1、XSS攻击</h2><p>XSS是一种常出现在Web应用中的计算机安全漏洞。</p>
<p>Web用户会将代码植入到页面之中，这些代码中包括HTML代码和客户端脚本。攻击者可以利用XSS的漏洞在web页面插入恶意的代码，达到对用户进行恶意攻击的目的。</p>
<h3 id="原理"><a href="#原理" class="headerlink" title="原理"></a>原理</h3><p>众所周知，HTML是一种超文本标记语言，通过一些设定的字符搭配来区分文本和标记，如&lt;title&gt;与&lt;/title&gt;之间的内容能够识别为html页面的标题，&lt;script&gt;与&lt;/script&gt;之间的内容识别为一段JavaScript脚本等等。</p>
<p>而如果在URL的参数中或在动态页面中插入的内容包含这些含有特殊含义的字符时，浏览器会误以为插入了HTML标签，当这些HTML标签引入了一段JavaScript脚本时，这些脚本程序会在用户浏览器中执行。</p>
<h3 id="XSS分类"><a href="#XSS分类" class="headerlink" title="XSS分类"></a>XSS分类</h3><h4 id="存储型XSS（也称持久型XSS）"><a href="#存储型XSS（也称持久型XSS）" class="headerlink" title="存储型XSS（也称持久型XSS）"></a>存储型XSS（也称持久型XSS）</h4><p>持久型XSS的最大特点是：服务器再接收到我们的恶意脚本时会将其做一些处理。例如储存到数据库中，然后当我们再次访问相同页面时，将恶意脚本从数据库中取出并返回给浏览器执行。这就意味着只要访问了这个页面的访客，都有可能会执行这段恶意脚本，因此储存型XSS的危害会更大。</p>
<p>还记得在文章开头提到的留言板的例子吗？那通常就是储存型XSS。当有人在留言内容中插入恶意脚本时，由于服务器要像每一个访客展示之前的留言内容，所以后面的访客自然会接收到之前留言中的恶意脚本而不幸躺枪。</p>
<p>这个过程一般而言只要用户访问这个界面就行了，不像反射型XSS，需要访问特定的URL。</p>
<h4 id="反射型XSS（也称非持久型XSS）"><a href="#反射型XSS（也称非持久型XSS）" class="headerlink" title="反射型XSS（也称非持久型XSS）"></a>反射型XSS（也称非持久型XSS）</h4><p>反射型XSS相对于访问者而言是一次性的，具体表现在我们把我们的恶意脚本通过url的方式传递给了服务器，而服务器则只是不加处理的把脚本“反射”回访问者的浏览器而使访问者的浏览器执行相应的脚本。</p>
<p>也就是说想要触发漏洞，需要访问特定的链接才能够实现。</p>
<h4 id="DOM-Based-XSS"><a href="#DOM-Based-XSS" class="headerlink" title="DOM Based XSS"></a>DOM Based XSS</h4><p>前两类的XSS可以通过“数据是否保存在服务器端”进行划分。</p>
<p>而DOM Based XSS是从反射型XSS中单独划分出来的、比较特别的XSS，因为此类XSS的形成原因比较特殊：DOM Based XSS是由于<strong>客户端脚本自身解析不正确</strong>导致的安全问题。</p>
<h2 id="2、XSS危害"><a href="#2、XSS危害" class="headerlink" title="2、XSS危害"></a>2、XSS危害</h2><p>归根结底，XSS的攻击方式就是想办法“教唆”用户的浏览器去执行一些这个网页中原本不存在的前端代码。</p>
<p>可问题在于尽管一个信息框突然弹出来并不怎么友好，但也不至于会造成什么真实伤害啊。的确如此，但要说明的是，这里拿信息框说事仅仅是为了举个栗子，真正的黑客攻击在XSS中除非恶作剧，不然是不会在恶意植入代码中写上alert（“say something”）的。</p>
<p>实例应用：</p>
<ul>
<li>劫持访问</li>
<li>盗用cookie实现无密码登录</li>
<li>结合CSRF攻击进行恶意请求</li>
</ul>
<h2 id="3、XSS防御"><a href="#3、XSS防御" class="headerlink" title="3、XSS防御"></a>3、XSS防御</h2><p>XSS防御的总体思路，<strong>对输入和URL参数进行过滤，对输出进行编码</strong>。</p>
<h4 id="（1）过滤"><a href="#（1）过滤" class="headerlink" title="（1）过滤"></a>（1）过滤</h4><p>对诸如&lt;script&gt;、&lt;img&gt;、&lt;a&gt;等标签进行过滤。</p>
<ul>
<li><strong>白名单和黑名单</strong>：</li>
</ul>
<h4 id="（2）编码"><a href="#（2）编码" class="headerlink" title="（2）编码"></a>（2）编码</h4><p>像一些常见的符号，如&lt;&gt;在输入的时候要对其进行转换编码，这样做浏览器是不会对该标签进行解释执行的，同时也不影响显示效果。</p>
<h4 id="（3）限制"><a href="#（3）限制" class="headerlink" title="（3）限制"></a>（3）限制</h4><p>通过以上的案例我们不难发现xss攻击要能达成往往需要较长的字符串，因此对于一些可以预期的输入可以通过<strong>限制长度强制截断</strong>来进行防御。</p>
<h3 id=""><a href="#" class="headerlink" title=""></a></h3>
      
      <!-- reward -->
      
    </div>
      <!-- copyright -->
      
    <footer class="article-footer">
      
      
  <ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/XSS%E6%94%BB%E5%87%BB/" rel="tag">XSS攻击</a></li></ul>


    </footer>

  </div>

  

  
  
  

  

</article>
    
    <article id="post-Java/JavaStructure" class="article article-type-post" itemscope
  itemprop="blogPost" data-scroll-reveal>

  <div class="article-inner">
    
    <header class="article-header">
       
<h2 itemprop="name">
  <a class="article-title" href="/2019/10/29/Java/JavaStructure/"
    >Java中的集合</a
  >
</h2>
  

    </header>
    

    
    <div class="article-meta">
      <a href="/2019/10/29/Java/JavaStructure/" class="article-date">
  <time datetime="2019-10-29T14:40:53.000Z" itemprop="datePublished">2019-10-29</time>
</a>
      
  <div class="article-category">
    <a class="article-category-link" href="/categories/Java/">Java</a>
  </div>

      
      
      
    </div>
    

    

    <div class="article-entry" itemprop="articleBody">
      


      

      
      <p>[TOC]</p>
<blockquote>
<p>Java集合体系结构（容器）主要有Set、LIst、Map三个接口</p>
</blockquote>
<h1 id="一、Collection"><a href="#一、Collection" class="headerlink" title="一、Collection"></a>一、Collection</h1><p><img src="http://static.zybuluo.com/Rico123/eu7lguy7qfpayqroq5l54veq/Collection.jpeg" alt="Set"></p>
<h2 id="1-1-添加一组元素的操作"><a href="#1-1-添加一组元素的操作" class="headerlink" title="1.1 添加一组元素的操作"></a>1.1 添加一组元素的操作</h2><ul>
<li><p>Arrays.asList()</p>
<ul>
<li><p>接受一个数组或用逗号隔开的元素列表，如：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">List&lt;Integer&gt; list = </span><br><span class="line">    Arrays.asList(array,<span class="number">1</span>,<span class="number">3</span>,<span class="number">5</span>);<span class="comment">//array为数组</span></span><br></pre></td></tr></table></figure>
</li>
<li><p>返回一个List对象</p>
</li>
<li><p>该方法只是对所产生的list类型做出了最理想的假设，并没有注意你对他赋予什么样的类型，解决方法：可以在其中间插入一条”线索”，这称为显示类型参数说明，如下：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">List&lt;Integer&gt; list = Arrays.&lt;Integer&gt;asList()</span><br></pre></td></tr></table></figure>
</li>
</ul>
</li>
<li><p>Collections.addAll()</p>
<ul>
<li><p>接受一个Collection对象，以及一个数组或一个用逗号分隔的元素列表，如：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Collections.addAll(list,<span class="number">2</span>,<span class="number">4</span>,<span class="number">6</span>);</span><br><span class="line"><span class="comment">//将元素添加到list（Collection类型）对象中</span></span><br></pre></td></tr></table></figure>
</li>
<li><p>无返回值，操作Collection对象参数</p>
</li>
</ul>
</li>
<li><p>Collection.addAll()</p>
<ul>
<li><p>只能接受另一个Collection对象作为参数，运行起来比较快，但没有前两者灵活，如：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Collection.addAll(list);</span><br></pre></td></tr></table></figure>



</li>
</ul>
</li>
</ul>
<h2 id="List"><a href="#List" class="headerlink" title="List"></a>List</h2><blockquote>
<p>List可以将元素维护在特定的序列中，该接口在Collection的基础上添加了大量方法，可以在List的中间插入和删除元素</p>
</blockquote>
<p>List是无序列表，主要实现的类有ArrayList、LinkedList、vertor；</p>
<h3 id="两种List类型"><a href="#两种List类型" class="headerlink" title="两种List类型"></a>两种List类型</h3><h4 id="1、ArrayList"><a href="#1、ArrayList" class="headerlink" title="1、ArrayList"></a>1、ArrayList</h4><blockquote>
<p>可以自动扩充自身尺寸的数组，擅长随机访问元素，但在ArrayList中插入和删除元素时较慢</p>
</blockquote>
<ul>
<li>add()——插入对象</li>
<li>get()——访问对象，需传入”数组下标”，不需[ ]（操作符重载实现）</li>
<li>size()——获取元素数量</li>
</ul>
<h4 id="2、LinkedList"><a href="#2、LinkedList" class="headerlink" title="2、LinkedList"></a>2、LinkedList</h4><blockquote>
<p>链表结构，在List中进行插入和删除操作的代价较低，提供了优化的顺序访问。其在随机访问方面相对比较慢</p>
</blockquote>
<p>LinkedList中还添加了可以使用它作为栈、队列或者双端队列的方法。</p>
<p>泛型在List中的作用：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">List&lt;Integer&gt; list = <span class="keyword">new</span> List&lt;&gt;();</span><br></pre></td></tr></table></figure>

<ul>
<li>指定了该容器实例能够保存的类型，可以在编译器防止将错误类型的对象放入到容器中；</li>
<li>在元素从容器中取出的时候，可以不用进行类型转换(因为容器通过泛型已经知道它保存的是什么类型)，在调用get()时会帮你进行类型转换</li>
<li>不需要使用容器中元素的索引时，可以使用foreach选择容器中的每个元素</li>
</ul>
<h3 id="常用方法"><a href="#常用方法" class="headerlink" title="常用方法"></a>常用方法</h3><ul>
<li>get()：返回指定下标（位置）的元素；</li>
<li>contains()：确定某个对象是否在列表中；</li>
<li>remove()：通过指定对象的引用从List中移除该对象；</li>
<li>indexOf()：通过指定对象的引用返回对象在List中对应的下标位置，不存在则返回-1；</li>
<li>subList()：从较大的List中创建出一个片段，且对subList所产生的列表的修改也会反映到初始列表中，反过来初始列表的修改也会反映到subList产生的列表中；</li>
<li>removeAll()：从List中移除所有的元素；</li>
<li>set()：在指定的索引处（第一个参数），用第二个参数替换该位置的元素；</li>
<li>addAll()：可以在指定位置（第一个参数）插入一段新的列表</li>
<li>isEmpty()：List为空时返回true</li>
<li>clear()：清空List</li>
<li>toArray()：转换为一个数组。</li>
<li>Queue的实现：<ul>
<li>element()：返回列表头（不移除），列表为空时抛出OnSuchElementException异常</li>
<li>offer()：在表尾添加元素</li>
<li>peek()：返回列表头，列表为空时返回null</li>
<li>poll()：移除并返回列表的头，列表为空时返回null</li>
<li>remove()：移除并返回列表的头，列表为空时抛出NoSuchElementException异常</li>
</ul>
</li>
</ul>
<h2 id="Iterator-迭代器"><a href="#Iterator-迭代器" class="headerlink" title="Iterator 迭代器"></a>Iterator 迭代器</h2><blockquote>
<p>也是一种设计模式。迭代器是一个对象，用于遍历并选择序列中的对象，而程序员可以不用关心该序列底层的结构</p>
</blockquote>
<p>Java中的Iterator只能单向移动，作用如下：</p>
<ul>
<li>使用方法Iterator()要求容器返回一个Iterator</li>
<li>使用next()获得序列中的下一个元素</li>
<li>使用hasNext()检查序列中是否还有元素</li>
<li>使用remove()将序列中的下一个元素移除</li>
</ul>
<blockquote>
<p>如果只是考虑遍历序列，不打算修改序列对象本身，使用foreach语法会显得更加简洁</p>
</blockquote>
<h3 id="真正的作用"><a href="#真正的作用" class="headerlink" title="真正的作用"></a>真正的作用</h3><p>能够将遍历或修改序列的操作与序列的底层结构分离，它<strong>统一了对容器的访问方式</strong></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">display</span><span class="params">(Iterator&lt;Integer&gt; it)</span></span>&#123;</span><br><span class="line">    						<span class="comment">//参数不关心容器是哪种类型</span></span><br><span class="line">    <span class="keyword">while</span>(it.hasNext())&#123;</span><br><span class="line">        <span class="keyword">int</span> i = it.next();</span><br><span class="line">        System.out.print(i+<span class="string">"  "</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<h2 id="Set"><a href="#Set" class="headerlink" title="Set"></a>Set</h2><blockquote>
<p>Set不保存重复的元素，其基于对象的值来确定归属性</p>
</blockquote>
<p> 实现了Collection接口，且没有额外的功能（Set实际上就是Collection，只是表现出不同的行为）；</p>
<p>Set接口主要实现的类有HashSet和TreeSet。</p>
<p>常用到的Set有HashSet，LinkedHashSet 和 TreeSet。</p>
<blockquote>
<ul>
<li>一般地，如果需要一个访问快速的Set，你应该使用HashSet；</li>
<li>当你需要一个排序的Set，你应该使用TreeSet；</li>
<li>当你需要记录下插入时的顺序时，你应该使用LinedHashSet。</li>
</ul>
</blockquote>
<h3 id="HashSet"><a href="#HashSet" class="headerlink" title="HashSet"></a>HashSet</h3><blockquote>
<p>HashSet，实现了Set接口，使用hash函数存储元素，其中的元素排列没有顺序。其add()、remove()以及 contains()等方法的复杂度为O(1)。</p>
</blockquote>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">HashSet</span>&lt;<span class="title">E</span>&gt;</span></span><br><span class="line"><span class="class">    <span class="keyword">extends</span> <span class="title">AbstractSet</span>&lt;<span class="title">E</span>&gt;</span></span><br><span class="line"><span class="class">    <span class="keyword">implements</span> <span class="title">Set</span>&lt;<span class="title">E</span>&gt;, <span class="title">Cloneable</span>, <span class="title">java</span>.<span class="title">io</span>.<span class="title">Serializable</span> </span>&#123;</span><br><span class="line">    <span class="keyword">static</span> <span class="keyword">final</span> <span class="keyword">long</span> serialVersionUID = -<span class="number">5024744406713321676L</span>;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 底层支持，HashMap可以代表一个HashMap，也可以代表一个LinkedHashMap</span></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">transient</span> HashMap&lt;E,Object&gt; map;     </span><br><span class="line"></span><br><span class="line">    <span class="comment">// Dummy value to associate with an Object in the backing Map</span></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> Object PRESENT = <span class="keyword">new</span> Object();    <span class="comment">// 傀儡对象</span></span><br></pre></td></tr></table></figure>

<h4 id="LinkedHashSet——HashSet-子类"><a href="#LinkedHashSet——HashSet-子类" class="headerlink" title="LinkedHashSet——HashSet 子类"></a>LinkedHashSet——HashSet 子类</h4><p>​    HashSet是HashSet的子类，其被委托到HashMap的子类LinkedHashMap进行实现，实现了Set接口。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">  * Constructs a new, empty linked hash set.  (This package private</span></span><br><span class="line"><span class="comment">  * constructor is only used by LinkedHashSet.) The backing</span></span><br><span class="line"><span class="comment">  * HashMap instance is a LinkedHashMap with the specified initial</span></span><br><span class="line"><span class="comment">  * capacity and the specified load factor.</span></span><br><span class="line"><span class="comment">  *</span></span><br><span class="line"><span class="comment">  * <span class="doctag">@param</span>      initialCapacity   the initial capacity of the hash map</span></span><br><span class="line"><span class="comment">  * <span class="doctag">@param</span>      loadFactor        the load factor of the hash map</span></span><br><span class="line"><span class="comment">  * <span class="doctag">@param</span>      dummy             ignored (distinguishes this</span></span><br><span class="line"><span class="comment">  *             constructor from other int, float constructor.)</span></span><br><span class="line"><span class="comment">  * <span class="doctag">@throws</span>     IllegalArgumentException if the initial capacity is less</span></span><br><span class="line"><span class="comment">  *             than zero, or if the load factor is nonpositive</span></span><br><span class="line"><span class="comment">  */</span></span><br><span class="line"> HashSet(<span class="keyword">int</span> initialCapacity, <span class="keyword">float</span> loadFactor, <span class="keyword">boolean</span> dummy) &#123;</span><br><span class="line"> map = <span class="keyword">new</span> LinkedHashMap&lt;E,Object&gt;(initialCapacity, loadFactor);</span><br><span class="line"> &#125;</span><br></pre></td></tr></table></figure>



<h3 id="TreeSet"><a href="#TreeSet" class="headerlink" title="TreeSet"></a>TreeSet</h3><p>​    TreeSet委托给TreeMap（其实现了NavigableSet接口）进行实现，实现了NavigableSet接口（SortedSet的扩展）</p>
<p>TreeSet将元素存储在<strong>红黑树</strong>数据结构中，结果有序</p>
<p>TreeSet默认是按照<strong>字典序</strong>排序的，如果想按照字母序排序，可以在TreeSet的构造器中传入String.CASE_INSENTIVE_ORDER比较器(比较器，建立排序顺序的对象)</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Set&lt;String&gt; set = </span><br><span class="line">    <span class="keyword">new</span> TreeSet&lt;String&gt;(String.CASE_INSENTIV_ORDER);</span><br></pre></td></tr></table></figure>



<p>其源码简述如下：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">TreeSet</span>&lt;<span class="title">E</span>&gt; <span class="keyword">extends</span> <span class="title">AbstractSet</span>&lt;<span class="title">E</span>&gt;</span></span><br><span class="line"><span class="class">    <span class="keyword">implements</span> <span class="title">NavigableSet</span>&lt;<span class="title">E</span>&gt;, <span class="title">Cloneable</span>, <span class="title">java</span>.<span class="title">io</span>.<span class="title">Serializable</span></span></span><br><span class="line"><span class="class"></span>&#123;</span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * The backing map.</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">transient</span> NavigableMap&lt;E,Object&gt; m;   <span class="comment">// 底层支持</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">// Dummy value to associate with an Object in the backing Map</span></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> Object PRESENT = <span class="keyword">new</span> Object();</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 默认构造函数</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">TreeSet</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>(<span class="keyword">new</span> TreeMap&lt;E,Object&gt;());</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>



<h2 id="Queue"><a href="#Queue" class="headerlink" title="Queue"></a>Queue</h2><blockquote>
<p>典型的先进先出FIFO容器</p>
</blockquote>
<p>相关方法：</p>
<ul>
<li>offer()：在允许的情况下，将一个元素插入到队尾</li>
<li>peek()、element()：在不移除的情况下返回队头<ul>
<li>peek()：队列为空时返回null</li>
<li>element()：队列为空时抛出NoSuchelementException异常</li>
</ul>
</li>
<li>poll()、remove()：移除并返回队头<ul>
<li>poll()：队列为空时返回null</li>
<li>remove()：队列为空时抛出NoSuchelementException异常</li>
</ul>
</li>
</ul>
<h1 id="二、Map"><a href="#二、Map" class="headerlink" title="二、Map"></a>二、Map</h1><p>Map为键值对，主要的实现类有HashMap，TreeMap和HashTable。</p>
<h2 id="HashMap"><a href="#HashMap" class="headerlink" title="HashMap"></a>HashMap</h2><h3 id="Java中HashMap与HashTable的联系与区别"><a href="#Java中HashMap与HashTable的联系与区别" class="headerlink" title="Java中HashMap与HashTable的联系与区别"></a>Java中HashMap与HashTable的联系与区别</h3><h4 id="HashMap与HashTable的联系"><a href="#HashMap与HashTable的联系" class="headerlink" title="HashMap与HashTable的联系"></a>HashMap与HashTable的联系</h4><ol>
<li>都实现了Map接口，保存了Key-Value（键值对）</li>
<li>两者的数据结构类似。HashMap和HashTable都是由数组元素为链表头节点的数组组成。</li>
</ol>
<h4 id="HashMap-与-HashTable-的区别"><a href="#HashMap-与-HashTable-的区别" class="headerlink" title="HashMap 与 HashTable 的区别"></a>HashMap 与 HashTable 的区别</h4><ol>
<li><p>两者继承的父类不同；</p>
<blockquote>
<p>HashMap继承AbstractMap类，而HashTable继承Dictionary类。</p>
</blockquote>
</li>
<li><p>HashMap是线程不安全的，而HashTable是线程安全的；</p>
<ol>
<li>HashMap在外部没有做同步处理的情况下，是非Synchronize（同步）的，不能保证在多并发条件下对数据的保护，容易产生脏数据；</li>
<li>HashTable中的方法是Synchronize的；可以在多并发环境下直接使用HashTable；</li>
</ol>
<blockquote>
<p>在单核CPU中HashMap的效率是比HashTable高的，而HashTable更适合在多线程中使用。</p>
</blockquote>
</li>
<li><p>提供contains：</p>
<ol>
<li>HashMap没有contians，只有containsKey和containsValue，认为contians会容易引起误解；</li>
<li>HashTable保留了contains，containsValue和containsKey方法。（但contains和containsValue的功能是相同的）</li>
</ol>
</li>
<li><p>对key和value的空值允许情况：</p>
<ol>
<li>HashMap中key和value都不允许为null；</li>
<li>HashTable中空值可以作为Key，也可以有一个/多个Key的值为空值；（其中的get()方法返回null的意思产生歧义，可能是该Key上的值为null，也可能是不存在该Key）</li>
</ol>
<blockquote>
<p>原因（也是HashMap与HashTable的区别之一）：当变量为null时，其hashcode（哈希值）也为null；</p>
<p>而<strong>两者对Key和Value的取值方式不同</strong></p>
<ul>
<li>HashMap中的Key值是直接取变量对应的 hashcode值 作为Key；</li>
<li>HashTable中会通过hash运算计算获取Value对应的Key；</li>
</ul>
</blockquote>
</li>
<li><p>HashMap和HashTable内部的数组初始化和扩容方式也不相同</p>
<ol>
<li>HashMap的hash数组默认长度大小为16，扩容方式为2的指数：<ul>
<li>length_HashMap = 16 * 2<sup>n</sup>（n为扩容次数）</li>
</ul>
</li>
<li>HashTable的hash数组默认长度大小为11，扩容方式为两倍加一：<ul>
<li>length_HashTable = (上一次HashTable数组长度) * 2 + 1</li>
</ul>
</li>
</ol>
</li>
</ol>
<h3 id="Java1-8的HashMap有什么改进吗？"><a href="#Java1-8的HashMap有什么改进吗？" class="headerlink" title="Java1.8的HashMap有什么改进吗？"></a>Java1.8的HashMap有什么改进吗？</h3><ul>
<li>1.8对HashMap的数据结构进行了改进，增加了判断是否变形为红黑树的阈值；1.7的HashMap使用链地址法进行哈希存储的，其中存在的明显的缺点便是当哈希因子所在的链表过长的时候，效率会很低；在1.8中增加了<strong>判断是否变形成为红黑树</strong>，它有一个阈值（8），当达到这个值时，链表便会变形成为红黑树。</li>
<li>1.8解决了resize时会造成死循环的问题。在1.7之中采用的是头插法，所以在迁移元素的时候，会将元素的顺序改变；1.8采用的是尾插法，能够很快的解决问题。</li>
</ul>
<h3 id="HashMap为什么要满足2n扩容"><a href="#HashMap为什么要满足2n扩容" class="headerlink" title="HashMap为什么要满足2n扩容"></a>HashMap为什么要满足2n扩容</h3><p>在resize时，key的hash值是要进行位运算的，初始容量为16（即2<sup>4</sup>），二进制表示为10000，将其二进制进行（n-1）&amp;hash；其中n-1得到01111，与hash值与运算便可保留前四位的值，结果与取余差不多，但效率比取余高，扩容满足2<sup>n</sup>的话，就依然能够保留二进制算法。</p>

      
      <!-- reward -->
      
    </div>
      <!-- copyright -->
      
    <footer class="article-footer">
      
      
  <ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/Java/" rel="tag">Java</a></li></ul>


    </footer>

  </div>

  

  
  
  

  

</article>
    
    <article id="w-Jpa/JpaPagingQuery" class="article article-type-w" itemscope
  itemprop="blogPost" data-scroll-reveal>

  <div class="article-inner">
    
    <header class="article-header">
       
<h2 itemprop="name">
  <a class="article-title" href="/2019/10/24/Jpa/JpaPagingQuery/"
    >JpaPagingQuery</a
  >
</h2>
  

    </header>
    

    
    <div class="article-meta">
      <a href="/2019/10/24/Jpa/JpaPagingQuery/" class="article-date">
  <time datetime="2019-10-24T14:00:51.000Z" itemprop="datePublished">2019-10-24</time>
</a>
      
  <div class="article-category">
    <a class="article-category-link" href="/categories/%E5%88%86%E9%A1%B5%E6%9F%A5%E8%AF%A2/">分页查询</a>
  </div>

      
      
      
    </div>
    

    

    <div class="article-entry" itemprop="articleBody">
      


      

      
      <h1 id="JPA分页查询方法"><a href="#JPA分页查询方法" class="headerlink" title="JPA分页查询方法"></a>JPA分页查询方法</h1><p>JpaRepository接口有提供如下表中所述的内置查询</p>
<table>
<thead>
<tr>
<th>方法</th>
<th>描述</th>
</tr>
</thead>
<tbody><tr>
<td>List findAll()</td>
<td>返回所有实体</td>
</tr>
<tr>
<td>List findAll(Iterable ids)</td>
<td>返回指定id的所有实体</td>
</tr>
<tr>
<td>T getOne(ID id)</td>
<td>根据id返回对应的实体，如果没找到，则返回null</td>
</tr>
<tr>
<td>List findAll(Sort sort)</td>
<td>返回所有实体，按照指定顺序返回</td>
</tr>
<tr>
<td>Page findAll(Pageable pageable)</td>
<td>返回实体列表，实体的offset和limit通过pageable来指定</td>
</tr>
</tbody></table>
<p>重点查看第五个方法</p>
<ul>
<li>pageRequest是Pageable的实现类，可以通过以下方法创建：</li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Param</span> page 从0开始，表示查询页</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Param</span> size 每页显示页数</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> PageRequest <span class="title">of</span><span class="params">(<span class="keyword">int</span> page,<span class="keyword">int</span> size)</span></span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Param</span> page 从0开始，表示查询页</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Param</span> size 每页显示页数</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Param</span> sort 排序方式</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> PageRequest <span class="title">of</span><span class="params">(<span class="keyword">int</span> page,<span class="keyword">int</span> size,Sort sort)</span></span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Param</span> page 从0开始，表示查询页</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Param</span> size 每页显示页数</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Param</span> direction 降序/升序</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> PageRequest <span class="title">of</span><span class="params">(<span class="keyword">int</span> page,<span class="keyword">int</span> size,Direction direction,String ... properties)</span></span>;</span><br></pre></td></tr></table></figure>



<ul>
<li>Page类</li>
</ul>
<ol>
<li>int getTotalPages() ：获取总页数</li>
<li>long getTotalElements()：返回总数</li>
<li>List getContent()：返回某页的结果集</li>
</ol>
<h2 id="EG"><a href="#EG" class="headerlink" title="EG"></a>EG</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Entity</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">User</span></span>&#123;</span><br><span class="line">    <span class="meta">@Id</span></span><br><span class="line">    <span class="meta">@GeneratedValue</span>(strategy = GenerationType.IDENTITY)</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">int</span> id;</span><br><span class="line">    </span><br><span class="line">    <span class="meta">@Column</span>(length = <span class="number">255</span>)</span><br><span class="line">    <span class="keyword">private</span> String name;</span><br><span class="line">    </span><br><span class="line">    <span class="meta">@Column</span>(length = <span class="number">2</span>)</span><br><span class="line">    <span class="keyword">private</span> String sex;</span><br><span class="line">    </span><br><span class="line">    <span class="meta">@Column</span>(length = <span class="number">255</span>)</span><br><span class="line">    <span class="keyword">private</span> String address;</span><br><span class="line">    </span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">User</span><span class="params">(<span class="keyword">int</span> id,String name,String sex,Strintg address)</span></span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.id = id;</span><br><span class="line">        <span class="keyword">this</span>.name = name;</span><br><span class="line">        <span class="keyword">this</span>.sex = sex;</span><br><span class="line">        <span class="keyword">this</span>.address = address;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">//getter , setter and toString</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Repository</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">UserRepository</span> <span class="keyword">extends</span> <span class="title">JpaRepository</span>&lt;<span class="title">User</span>,<span class="title">Integer</span>&gt;</span>&#123;</span><br><span class="line">    </span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">testJpaQuery</span><span class="params">()</span></span>&#123;</span><br><span class="line">    PageRequest pageRequest = PageRequest.of(<span class="number">0</span>,<span class="number">2</span>);</span><br><span class="line">    Page&lt;User&gt; page = userRepository.findAll(pageRequest);</span><br><span class="line">    List&lt;User&gt; users = page.getContent();</span><br><span class="line">    <span class="keyword">for</span>(User u : users)&#123;</span><br><span class="line">        System.out.println(u);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>


      
      <!-- reward -->
      
    </div>
      <!-- copyright -->
      
    <footer class="article-footer">
      
      
  <ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/Java/" rel="tag">Java</a></li></ul>


    </footer>

  </div>

  

  
  
  

  

</article>
    
    <article id="post-Netty/【Netty】Netty简介" class="article article-type-post" itemscope
  itemprop="blogPost" data-scroll-reveal>

  <div class="article-inner">
    
    <header class="article-header">
       
<h2 itemprop="name">
  <a class="article-title" href="/2019/10/21/Netty/%E3%80%90Netty%E3%80%91Netty%E7%AE%80%E4%BB%8B/"
    >【Netty】Netty简介</a
  >
</h2>
  

    </header>
    

    
    <div class="article-meta">
      <a href="/2019/10/21/Netty/%E3%80%90Netty%E3%80%91Netty%E7%AE%80%E4%BB%8B/" class="article-date">
  <time datetime="2019-10-21T14:27:21.000Z" itemprop="datePublished">2019-10-21</time>
</a>
      
  <div class="article-category">
    <a class="article-category-link" href="/categories/Netty%E5%9F%BA%E7%A1%80/">Netty基础</a>
  </div>

      
      
      
    </div>
    

    

    <div class="article-entry" itemprop="articleBody">
      


      

      
      <h1 id="【Netty】初探"><a href="#【Netty】初探" class="headerlink" title="【Netty】初探"></a>【Netty】初探</h1><h2 id="走进Java-NIO"><a href="#走进Java-NIO" class="headerlink" title="走进Java NIO"></a>走进Java NIO</h2><h3 id="同步阻塞BIO"><a href="#同步阻塞BIO" class="headerlink" title="同步阻塞BIO"></a>同步阻塞BIO</h3><p>同步阻塞I/O，服务器实现模式为一个连接一个线程，即<strong>客户端有连接请求时服务器就需要启动一个线程进行处理</strong>，如果这个连接不做任何事情会造成不必要的线程开销，可以通过<strong>线程池机制</strong>来改善。</p>
<p>BIO方式适用于<strong>连接数目比较小且固定的架构</strong>，这种方式对服务端资源要求比较高，并发局限于应用中，在jdk1.4以前是唯一的io，但程序直观简单易理解</p>
<h3 id="伪同步I-O"><a href="#伪同步I-O" class="headerlink" title="伪同步I/O"></a>伪同步I/O</h3><h3 id="同步非阻塞NIO（New-IO-Non-block-IO）"><a href="#同步非阻塞NIO（New-IO-Non-block-IO）" class="headerlink" title="同步非阻塞NIO（New IO/Non-block IO）"></a>同步非阻塞NIO（New IO/Non-block IO）</h3><p>同步非阻塞IO，服务器实现模式为<strong>一个请求一个线程</strong>，即客户端发送的连接请求都会注册到多路复用器上，多路复用器轮询到连接有io请求时候，会启动一个线程进行处理。</p>
<p>NIO适用于<strong>连接数目多且连接短</strong>的架构，比如聊天服务器，并发局限于应用中，编程比较复杂。在jdk1.4开始支持。</p>
<h3 id="异步非阻塞AIO"><a href="#异步非阻塞AIO" class="headerlink" title="异步非阻塞AIO"></a>异步非阻塞AIO</h3><p>异步非阻塞io，也称NIO.2，服务器实现模式为<strong>一个有效请求一个线程</strong>，客户端IO请求都是<strong>操作系统先完成了再通知服务器启动线程进行处理</strong>。</p>
<p>AIO适用于<strong>连接数目多且连接比较长（重操作）</strong>的架构，如相册服务器，充分调用OS参与并发操作，编程比较复杂，jdk1.7开始支持。</p>
<h3 id="IO和NIO的区别"><a href="#IO和NIO的区别" class="headerlink" title="IO和NIO的区别"></a>IO和NIO的区别</h3><ul>
<li>IO面向流，NIO面向缓冲区</li>
<li>IO的各个流是阻塞的，NIO是非阻塞模式</li>
</ul>
<h3 id="四种IO的区别"><a href="#四种IO的区别" class="headerlink" title="四种IO的区别"></a>四种IO的区别</h3><h2 id="Netty入门应用"><a href="#Netty入门应用" class="headerlink" title="Netty入门应用"></a>Netty入门应用</h2><h3 id="Netty架构深入解析"><a href="#Netty架构深入解析" class="headerlink" title="Netty架构深入解析"></a>Netty架构深入解析</h3><h2 id="Java多线程编程在Netty中的应用"><a href="#Java多线程编程在Netty中的应用" class="headerlink" title="Java多线程编程在Netty中的应用"></a>Java多线程编程在Netty中的应用</h2><h2 id="Netty的未来"><a href="#Netty的未来" class="headerlink" title="Netty的未来"></a>Netty的未来</h2>
      
      <!-- reward -->
      
    </div>
      <!-- copyright -->
      
    <footer class="article-footer">
      
      
  <ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/Netty/" rel="tag">Netty</a></li></ul>


    </footer>

  </div>

  

  
  
  

  

</article>
    
    <article id="post-Redis/【Redis】Redis简介" class="article article-type-post" itemscope
  itemprop="blogPost" data-scroll-reveal>

  <div class="article-inner">
    
    <header class="article-header">
       
<h2 itemprop="name">
  <a class="article-title" href="/2019/10/21/Redis/%E3%80%90Redis%E3%80%91Redis%E7%AE%80%E4%BB%8B/"
    >【Redis】Redis简介</a
  >
</h2>
  

    </header>
    

    
    <div class="article-meta">
      <a href="/2019/10/21/Redis/%E3%80%90Redis%E3%80%91Redis%E7%AE%80%E4%BB%8B/" class="article-date">
  <time datetime="2019-10-21T13:54:50.000Z" itemprop="datePublished">2019-10-21</time>
</a>
      
  <div class="article-category">
    <a class="article-category-link" href="/categories/Redis%E5%9F%BA%E7%A1%80/">Redis基础</a>
  </div>

      
      
      
    </div>
    

    

    <div class="article-entry" itemprop="articleBody">
      


      

      
      <h1 id="Redis"><a href="#Redis" class="headerlink" title="Redis"></a>Redis</h1><h2 id="Redis简介"><a href="#Redis简介" class="headerlink" title="Redis简介"></a>Redis简介</h2><p>Redis 是完全开源免费的，遵守 BSD 协议，是一个高性能的 key - value 数据库</p>
<p>Redis 与 其他 key - value 缓存产品有以下三个特点：</p>
<ul>
<li>Redis 支持数据持久化，可以将内存中的数据保存在磁盘中，重启的时候可以再次加载进行使用。</li>
<li>Redis 不仅仅支持简单的 key - value 类型的数据，同时还提供 list，set，zset，hash 等数据结构的存储</li>
<li>Redis 支持数据的备份，即 master - slave 模式的数据备份</li>
</ul>
<h2 id="Redis数据类型"><a href="#Redis数据类型" class="headerlink" title="Redis数据类型"></a>Redis数据类型</h2><table>
<thead>
<tr>
<th align="center">结构类型</th>
<th align="center">结构存储的值</th>
<th align="center">读写能力</th>
</tr>
</thead>
<tbody><tr>
<td align="center">String</td>
<td align="center">可以是字符串，整数或者浮点数</td>
<td align="center">可以对整个字符串或者字符串中的一部分进行操作，对整数和浮点数执行自增或者自减操作</td>
</tr>
<tr>
<td align="center">List</td>
<td align="center">一个链表，链表上的每个节点都包含一个字符串</td>
<td align="center">从链表两端添加元素或者弹出元素，<strong>根据偏移量对链表进行修剪</strong>；读取单个或者多个元素，根据值查找或溢出元素</td>
</tr>
<tr>
<td align="center">Set</td>
<td align="center">包含字符串的无序集合，且其中的每个字符串都是各不相同的</td>
<td align="center">添加、获取、删除单个元素，检查一个元素是否存在于集合中，计算交集、并集、差集；从集合中随机获取元素</td>
</tr>
<tr>
<td align="center">Hash</td>
<td align="center">包含键值对的无序哈希表</td>
<td align="center">添加、获取、删除单个键值对，获取所有键值对</td>
</tr>
<tr>
<td align="center">Zset</td>
<td align="center">字符串成员与浮点数分支之间的有序映射，元素的排列顺序由分值的大小决定</td>
<td align="center">添加、获取、删除单个元素，根据分支范围（range）或者成员来获取元素。</td>
</tr>
</tbody></table>
<h2 id="事务"><a href="#事务" class="headerlink" title="事务"></a>事务</h2><p>redis事务一次可以执行多条命令，服务器在执行命令期间，不会执行其他客户端的命令请求。</p>
<p>事务中的一条或多条命令被一次性发送到服务器，并不是逐条发送，此种方式被称为流水线，可以减少客户端与服务器之间的网络通信次数，提升性能。</p>
<p>Redis一般的事务实现方式：使用MULTI和EXEC命令将事务操作包起来：</p>
<ol>
<li>批量操作在发送EXEC命令前被放入队列缓存；</li>
<li>收到EXEC命令后进入事务执行，事务中任意命令执行失败，其余命令依然被执行。也就是说Redis事务不保证原子性；</li>
<li>在事务执行过程中，其他客户端提交的命令不会插入到事务执行命令序列中；</li>
</ol>
<p>一个事务从开始到执行过程中经历的三个阶段：</p>
<ul>
<li>开始事务；</li>
<li>命令入队；</li>
<li>执行事务；</li>
</ul>
<p>eg：</p>
<figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">MULTI	<span class="comment">--1、开始事务</span></span><br><span class="line"></span><br><span class="line"><span class="comment">--2、命令入队</span></span><br><span class="line"><span class="keyword">SET</span> book-<span class="keyword">name</span> <span class="string">"Mastering C++ in 21 days"</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">Get</span> book-<span class="keyword">name</span></span><br><span class="line"></span><br><span class="line">SADD tag <span class="string">"C++"</span> <span class="string">"Programming"</span> <span class="string">"Mastering Series"</span></span><br><span class="line"></span><br><span class="line">SMEMBERS tag</span><br><span class="line"></span><br><span class="line">EXEC	<span class="comment">--3、执行事务</span></span><br></pre></td></tr></table></figure>



<blockquote>
<p>单个命令的执行是原子性的，但是Redis没有在事务上增加任何维持原子性的机制，所以Redis事务的执行并不是原子性的。</p>
<p>Redis的事务，可以理解是一个打包好的、批量的执行脚本，但是这些批量的指令并不是原子化的操作，中间某条指令的失败，不会导致事务中之前执行的指令的回滚，也不会导致之后的指令不会执行。</p>
<p>官网相关内容说明：</p>
<p> <em>It’s important to note that even when a command fails, all the other commands in the queue are processed – Redis will not stop the processing of commands</em> </p>
</blockquote>
<h3 id="Redis事务命令"><a href="#Redis事务命令" class="headerlink" title="Redis事务命令"></a>Redis事务命令</h3><table>
<thead>
<tr>
<th align="center">命令</th>
<th align="center">描述</th>
</tr>
</thead>
<tbody><tr>
<td align="center">DISCARD</td>
<td align="center">取消事务，放弃执行事务块内的所有命令</td>
</tr>
<tr>
<td align="center">EXEC</td>
<td align="center">执行所有事务块内的命令</td>
</tr>
<tr>
<td align="center">MULTI</td>
<td align="center">标记事务块的开始</td>
</tr>
<tr>
<td align="center">UNWATCH</td>
<td align="center">取消Watch命令对所有key的监视</td>
</tr>
<tr>
<td align="center">WATCH key [key …]</td>
<td align="center">监视一个/多个key，如果在事务执行之前这个/些 key 被其他命令改动<br>则该事务将被打断</td>
</tr>
</tbody></table>
<h2 id="Redis-持久化"><a href="#Redis-持久化" class="headerlink" title="Redis 持久化"></a>Redis 持久化</h2><p>Redis 是内存型数据库，为了保证数据在断电后不会丢失，需要将内存中的数据持久化到硬盘上。</p>
<h3 id="（1）RDB-持久化"><a href="#（1）RDB-持久化" class="headerlink" title="（1）RDB 持久化"></a>（1）RDB 持久化</h3><p>将某个时间点的所有数据都存放到硬盘上。</p>
<p>可以将快照复制到其他服务器从而创建具有相同数据的服务器副本。</p>
<p>如果系统发生故障，将会丢失最后一次创建快照之后的数据。</p>
<p>如果数据量大，保存快照的时间会很长。</p>
<h3 id="（2）AOF-持久化"><a href="#（2）AOF-持久化" class="headerlink" title="（2）AOF 持久化"></a>（2）AOF 持久化</h3><p>将写命令添加到 AOF 文件（append only file）末尾。</p>
<p>使用 AOF 持久化需要设置同步选项，从而确保<strong>写命令</strong>同步到磁盘文件上的时机。</p>
<p>这是因为对文件进行写入并不会马上将内容同步到磁盘上，而是先存储到缓冲区，然后由操作系统决定什么时候同步到磁盘。</p>
<p>选项同步频率always每个写命令都同步eyerysec每秒同步一次no让操作系统来决定何时同步</p>
<ul>
<li>always 选项会严重减低服务器的性能</li>
<li>everysec 选项比较合适，可以保证系统崩溃时只会丢失一秒左右的数据，并且 Redis 每秒执行一次同步对服务器几乎没有任何影响。</li>
<li>no 选项并不能给服务器性能带来多大的提升，而且会增加系统崩溃时数据丢失的数量。</li>
</ul>
<p>随着服务器写请求的增多，AOF 文件会越来越大。Redis 提供了一种将 AOF 重写的特性，能够去除 AOF 文件中的冗余写命令。</p>
<h2 id="复制"><a href="#复制" class="headerlink" title="复制"></a>复制</h2><p>通过使用 slaveof host port 命令来让一个服务器成为另一个服务器的从服务器。</p>
<p>一个从服务器只能有一个主服务器，并且不支持主主复制。</p>
<h3 id="连接过程"><a href="#连接过程" class="headerlink" title="连接过程"></a>连接过程</h3><ol>
<li>主服务器创建快照文件，即 RDB 文件，发送给从服务器，并在发送期间使用缓冲区记录执行的写命令。</li>
<li>快照文件发送完毕之后，开始像从服务器发送存储在缓冲区的写命令。</li>
<li>从服务器丢弃所有旧数据，载入主服务器发来的快照文件，之后从服务器开始接受主服务器发来的写命令。</li>
<li>主服务器每执行一次写命令，就向从服务器发送相同的写命令。</li>
</ol>
<h3 id="主从链"><a href="#主从链" class="headerlink" title="主从链"></a>主从链</h3><p>随着负载不断上升，主服务器无法很快的更新所有从服务器，或者重新连接和重新同步从服务器将导致系统超载。</p>
<p>为了解决这个问题，可以创建一个中间层来分担主服务器的复制工作。中间层的服务器是最上层服务器的从服务器，又是最下层服务器的主服务器。</p>
<h2 id="哨兵"><a href="#哨兵" class="headerlink" title="哨兵"></a>哨兵</h2><p>Sentinel（哨兵）可以监听集群中的服务器，并在主服务器进入下线状态时，自动从从服务器中选举处新的主服务器。</p>
<h2 id="分片"><a href="#分片" class="headerlink" title="分片"></a>分片</h2><p>分片是将数据划分为多个部分的方法，可以将数据存储到多台机器里面，这种方法在解决某些问题时可以获得线性级别的性能提升。</p>
<p>假设有 4 个 Redis 实例 R0, R1, R2, R3, 还有很多表示用户的键 user:1, user:2, … , 有不同的方式来选择一个指定的键存储在哪个实例中。</p>
<ul>
<li>最简单的是范围分片，例如用户 id 从 0 ~ 1000 的存储到实例 R0 中，用户 id 从 1001 ~ 2000 的存储到实例 R1中，等等。但是这样需要维护一张映射范围表，维护操作代价高。</li>
<li>还有一种是哈希分片。使用 CRC32 哈希函数将键转换为一个数字，再对实例数量求模就能知道存储的实例。</li>
</ul>
<p>根据执行分片的位置，可以分为三种分片方式：</p>
<ul>
<li>客户端分片：客户端使用一致性哈希等算法决定应当分布到哪个节点。</li>
<li>代理分片：将客户端的请求发送到代理上，由代理转发到正确的节点上。</li>
<li>服务器分片：Redis Cluster。</li>
</ul>

      
      <!-- reward -->
      
    </div>
      <!-- copyright -->
      
    <footer class="article-footer">
      
      
  <ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/Redis/" rel="tag">Redis</a></li></ul>


    </footer>

  </div>

  

  
  
  

  

</article>
    
    <article id="post-DistributedArchitecture/分布式架构体系" class="article article-type-post" itemscope
  itemprop="blogPost" data-scroll-reveal>

  <div class="article-inner">
    
    <header class="article-header">
       
<h2 itemprop="name">
  <a class="article-title" href="/2019/10/19/DistributedArchitecture/%E5%88%86%E5%B8%83%E5%BC%8F%E6%9E%B6%E6%9E%84%E4%BD%93%E7%B3%BB/"
    >分布式架构体系</a
  >
</h2>
  

    </header>
    

    
    <div class="article-meta">
      <a href="/2019/10/19/DistributedArchitecture/%E5%88%86%E5%B8%83%E5%BC%8F%E6%9E%B6%E6%9E%84%E4%BD%93%E7%B3%BB/" class="article-date">
  <time datetime="2019-10-19T13:56:28.000Z" itemprop="datePublished">2019-10-19</time>
</a>
      
      
      
      
    </div>
    

    

    <div class="article-entry" itemprop="articleBody">
      


      

      
      
      
      <!-- reward -->
      
    </div>
      <!-- copyright -->
      
    <footer class="article-footer">
      
      
  <ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/%E5%88%86%E5%B8%83%E5%BC%8F/" rel="tag">分布式</a></li></ul>


    </footer>

  </div>

  

  
  
  

  

</article>
    
  </article>
  

  
  <nav class="page-nav">
    
    <a class="extend prev" rel="prev" href="/page/4/">上一页</a><a class="page-number" href="/">1</a><span class="space">&hellip;</span><a class="page-number" href="/page/3/">3</a><a class="page-number" href="/page/4/">4</a><span class="page-number current">5</span><a class="page-number" href="/page/6/">6</a><a class="extend next" rel="next" href="/page/6/">下一页</a>
  </nav>
  
</section>
</div>

      <footer class="footer">
  <div class="outer">
    <ul class="list-inline">
      <li>
        &copy;
        2019-2020
        LinPaiBin
      </li>
      <li>
        
          Powered by
        
        
        <a href="https://hexo.io" target="_blank">Hexo</a> Theme <a href="https://github.com/Shen-Yu/hexo-theme-ayer" target="_blank">Ayer</a>
        
      </li>
    </ul>
    <ul class="list-inline">
      <li>
        
        
        <span>
  <i>PV:<span id="busuanzi_value_page_pv"></span></i>
  <i>UV:<span id="busuanzi_value_site_uv"></span></i>
</span>
        
      </li>
      <li>
        <!-- cnzz统计 -->
        
        <script type="text/javascript" src='https://s9.cnzz.com/z_stat.php?id=1278069914&amp;web_id=1278069914'></script>
        
      </li>
    </ul>
  </div>
</footer>
    <div class="to_top">
        <div class="totop" id="totop">
  <i class="ri-arrow-up-line"></i>
</div>
      </div>
    </main>
      <aside class="sidebar">
        <button class="navbar-toggle"></button>
<nav class="navbar" style="opacity: 0.5;">
  
  <div class="logo">
    <a href="/"><img src="/images/ayer-side.svg" alt="滨书"></a>
  </div>
  
  <ul class="nav nav-main">
    
    <li class="nav-item">
      <a class="nav-item-link" href="/">主页</a>
    </li>
    
    <li class="nav-item">
      <a class="nav-item-link" href="/archives">归档</a>
    </li>
    
    <li class="nav-item">
      <a class="nav-item-link" href="/categories">分类</a>
    </li>
    
    <li class="nav-item">
      <a class="nav-item-link" href="/tags">标签</a>
    </li>
    
    <li class="nav-item">
      <a class="nav-item-link" href="/tags/%E7%94%9F%E6%B4%BB/">生活</a>
    </li>
    
    <li class="nav-item">
      <a class="nav-item-link" href="/2019/12/02/AboutMe">关于我</a>
    </li>
    
  </ul>
</nav>
<nav class="navbar navbar-bottom">
  
  <ul class="nav">
    <li class="nav-item">
      
      <a class="nav-item-link nav-item-search"  title="Search">
        <i class="ri-search-line"></i>
      </a>
      
      
      <a class="nav-item-link" target="_blank" href="/atom.xml" title="RSS Feed">
        <i class="ri-rss-line"></i>
      </a>
      
    </li>
  </ul>
</nav>
<div class="search-form-wrap">
  <div class="local-search local-search-plugin">
  <input type="search" id="local-search-input" class="local-search-input" placeholder="Search...">
  <div id="local-search-result" class="local-search-result"></div>
</div>
</div>
      </aside>
      <div id="mask"></div>

<!-- #reward -->
<div id="reward">
  <span class="close"><i class="ri-close-line"></i></span>
  <p class="reward-p"><i class="ri-cup-line"></i>请我喝杯咖啡吧~</p>
  <div class="reward-box">
    
    <div class="reward-item">
      <img class="reward-img" src="/images/alipay.jpg">
      <span class="reward-type">支付宝</span>
    </div>
    
    
    <div class="reward-item">
      <img class="reward-img" src="/images/wechat.jpg">
      <span class="reward-type">微信</span>
    </div>
    
  </div>
</div>
      
<script src="/js/jquery-2.0.3.min.js"></script>


<script src="/js/jquery.justifiedGallery.min.js"></script>


<script src="/js/lazyload.min.js"></script>


<script src="/js/busuanzi-2.3.pure.min.js"></script>


<script src="/js/share.js"></script>



<script src="/fancybox/jquery.fancybox.min.js"></script>




<script>
  try {
    var typed = new Typed("#subtitle", {
    strings: ['人生如棋，吾愿为卒','愿你一生努力，一生无憾','不求事事顺意，但求无愧于心'],
    startDelay: 0,
    typeSpeed: 250,
    loop: true,
    backSpeed: 100,
    showCursor: true
    });
  } catch (err) {
  }
  
</script>




<script>
  var ayerConfig = {
    mathjax: false
  }
</script>


<script src="/js/ayer.js"></script>


<script src="https://cdn.jsdelivr.net/npm/jquery-modal@0.9.2/jquery.modal.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/jquery-modal@0.9.2/jquery.modal.min.css">


<!-- Root element of PhotoSwipe. Must have class pswp. -->
<div class="pswp" tabindex="-1" role="dialog" aria-hidden="true">

    <!-- Background of PhotoSwipe. 
         It's a separate element as animating opacity is faster than rgba(). -->
    <div class="pswp__bg"></div>

    <!-- Slides wrapper with overflow:hidden. -->
    <div class="pswp__scroll-wrap">

        <!-- Container that holds slides. 
            PhotoSwipe keeps only 3 of them in the DOM to save memory.
            Don't modify these 3 pswp__item elements, data is added later on. -->
        <div class="pswp__container">
            <div class="pswp__item"></div>
            <div class="pswp__item"></div>
            <div class="pswp__item"></div>
        </div>

        <!-- Default (PhotoSwipeUI_Default) interface on top of sliding area. Can be changed. -->
        <div class="pswp__ui pswp__ui--hidden">

            <div class="pswp__top-bar">

                <!--  Controls are self-explanatory. Order can be changed. -->

                <div class="pswp__counter"></div>

                <button class="pswp__button pswp__button--close" title="Close (Esc)"></button>

                <button class="pswp__button pswp__button--share" style="display:none" title="Share"></button>

                <button class="pswp__button pswp__button--fs" title="Toggle fullscreen"></button>

                <button class="pswp__button pswp__button--zoom" title="Zoom in/out"></button>

                <!-- Preloader demo http://codepen.io/dimsemenov/pen/yyBWoR -->
                <!-- element will get class pswp__preloader--active when preloader is running -->
                <div class="pswp__preloader">
                    <div class="pswp__preloader__icn">
                        <div class="pswp__preloader__cut">
                            <div class="pswp__preloader__donut"></div>
                        </div>
                    </div>
                </div>
            </div>

            <div class="pswp__share-modal pswp__share-modal--hidden pswp__single-tap">
                <div class="pswp__share-tooltip"></div>
            </div>

            <button class="pswp__button pswp__button--arrow--left" title="Previous (arrow left)">
            </button>

            <button class="pswp__button pswp__button--arrow--right" title="Next (arrow right)">
            </button>

            <div class="pswp__caption">
                <div class="pswp__caption__center"></div>
            </div>

        </div>

    </div>

</div>

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/photoswipe.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/default-skin/default-skin.css">
<script src="https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/photoswipe.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/photoswipe-ui-default.min.js"></script>

<script>
    function viewer_init() {
        let pswpElement = document.querySelectorAll('.pswp')[0];
        let $imgArr = document.querySelectorAll(('.article-entry img:not(.reward-img)'))

        $imgArr.forEach(($em, i) => {
            $em.onclick = () => {
                // slider展开状态
                // todo: 这样不好，后面改成状态
                if (document.querySelector('.left-col.show')) return
                let items = []
                $imgArr.forEach(($em2, i2) => {
                    let img = $em2.getAttribute('data-idx', i2)
                    let src = $em2.getAttribute('data-target') || $em2.getAttribute('src')
                    let title = $em2.getAttribute('alt')
                    // 获得原图尺寸
                    const image = new Image()
                    image.src = src
                    items.push({
                        src: src,
                        w: image.width || $em2.width,
                        h: image.height || $em2.height,
                        title: title
                    })
                })
                var gallery = new PhotoSwipe(pswpElement, PhotoSwipeUI_Default, items, {
                    index: parseInt(i)
                });
                gallery.init()
            }
        })
    }
    viewer_init()
</script>




<script type="text/javascript" src="https://js.users.51.la/20544303.js"></script>
  </div>
</body>

</html>